package com.test.daily.leetcode.y2021.m10.day1006;

import java.util.Comparator;
import java.util.PriorityQueue;

/**
 * ThirdMax
 *
 * @author Tom on 2021/10/6
 */
public class Algo01_ThirdMax {
    public static void main(String[] args) {
        int[] arr = new int[]{5, 2, 2};
        System.out.println(thirdMax2(arr));
    }

    public static int thirdMax(int[] nums) {
        if (nums.length == 1) {
            return nums[0];
        }
        if (nums.length == 2) {
            return Math.max(nums[0], nums[1]);
        }
        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(new ThirdMaxCompare());
        for (int i = 0; i < nums.length; i++) {
            if (!priorityQueue.contains(nums[i])) {
                priorityQueue.add(nums[i]);
            }
        }
        while (priorityQueue.size() > 3) {
            priorityQueue.poll();
        }
        if (priorityQueue.size() == 2) {
            priorityQueue.poll();
        }
        return priorityQueue.poll();
    }

    public static class ThirdMaxCompare implements Comparator<Integer> {
        @Override
        public int compare(Integer o1, Integer o2) {
            if (o1 < 0 && o2 > 0) {
                return -1;
            }
            if (o1 > 0 && o2 < 0) {
                return 1;
            }
            return o1 - o2;
        }
    }

    public static int thirdMax2(int[] nums) {
        long max, mid, min;
        if (nums.length == 1) {
            return nums[0];
        }
        if (nums.length == 2) {
            return Math.max(nums[0], nums[1]);
        }
        max = Long.MIN_VALUE;
        mid = Long.MIN_VALUE;
        min = Long.MIN_VALUE;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] > max) {
                min = mid;
                mid = max;
                max = nums[i];
            } else if (nums[i] < max && nums[i] > mid) {
                min = mid;
                mid = nums[i];
            } else if (nums[i] < mid && nums[i] > min) {
                min = nums[i];
            }
        }
        return min == Long.MIN_VALUE? (int)max: (int)min;
    }

    public int thirdMax3(int[] nums) {
        long max = Long.MIN_VALUE, mid = Long.MIN_VALUE, min = Long.MIN_VALUE;
        for (long num : nums) {
            if (num > max) {
                min = mid;
                mid = max;
                max = num;
            } else if (max > num && num > mid) {
                min = mid;
                mid = num;
            } else if (mid > num && num > min) {
                min = num;
            }
        }
        return min == Long.MIN_VALUE ? (int) max : (int) min;
    }
}